package com.mysteel.monitor.core.component;

import com.mysteel.monitor.core.model.GarbageInfo;
import com.mysteel.monitor.core.model.MemoryUsageInfo;
import com.mysteel.monitor.core.model.SystemInfo;
import com.mysteel.monitor.core.utils.PidUtils;
import com.mysteel.monitor.core.utils.Utils;

import java.lang.management.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Administrator
 */

public class SystemComponent {


    /**
     *  获取系统ip和主机名称
     * @return
     */
    public  String ipAndhostName(){
        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        if(addr != null ){
            return String.format("IP:%s,主机名称：%s, PID: %s",addr.getHostAddress(),addr.getHostName(), PidUtils.currentPid());
        }else{
            return String.format("IP:%s,主机名称：%s","","");
        }

    }

    /**
     *  显示新系统信息
     * @return
     */
    public SystemInfo initSystemInfo() {

        SystemInfo systemInfo = SystemInfo.builder()
                .osName(System.getProperty("os.name"))
                .osVersion(System.getProperty("os.version"))
                .javaVersion(System.getProperty("java.version"))
                .javaHome(System.getProperty("java.home"))
                // 负载均衡
                .systemload(String.format("%.2f", ManagementFactory.getOperatingSystemMXBean().getSystemLoadAverage()))
                .processors(Runtime.getRuntime().availableProcessors())
                // 启动时间
                .uptime(Utils.formatTime(ManagementFactory.getRuntimeMXBean().getUptime()))
                .build();
        return systemInfo;
    }

    /**
     *  内存使用信息
     * @return
     */
    public List<MemoryUsageInfo> memoryUsageInfos() {

        List<MemoryUsageInfo> memoryUsageInfoList = new ArrayList<>();
        MemoryUsage heapMemoryUsage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
        MemoryUsage nonHeapMemoryUsage = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
        List<MemoryPoolMXBean> memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans();
        // 堆信息
        memoryUsageInfoList.add(new MemoryUsageInfo(MemoryType.HEAP.name(),"heap", heapMemoryUsage));
        for (MemoryPoolMXBean poolMXBean : memoryPoolMXBeans) {
            if (MemoryType.HEAP.equals(poolMXBean.getType())) {
                MemoryUsage usage = poolMXBean.getUsage();
                String poolName = poolMXBean.getName();
                memoryUsageInfoList.add(new MemoryUsageInfo(MemoryType.HEAP.name(),poolName, usage));
            }
        }
        // 非堆区
        memoryUsageInfoList.add(new MemoryUsageInfo(MemoryType.NON_HEAP.name(),"nonheap", nonHeapMemoryUsage));
        for (MemoryPoolMXBean poolMXBean : memoryPoolMXBeans) {
            if (MemoryType.NON_HEAP.equals(poolMXBean.getType())) {
                MemoryUsage usage = poolMXBean.getUsage();
                String poolName = poolMXBean.getName();
                memoryUsageInfoList.add(new MemoryUsageInfo(MemoryType.NON_HEAP.name(),poolName, usage));
            }
        }
        try {
            // 缓冲池
            Class bufferPoolMXBeanClass = Class.forName("java.lang.management.BufferPoolMXBean");
            @SuppressWarnings("unchecked")
            List<BufferPoolMXBean> bufferPoolMXBeans = ManagementFactory.getPlatformMXBeans(bufferPoolMXBeanClass);
            for (BufferPoolMXBean mbean : bufferPoolMXBeans) {
                long used = mbean.getMemoryUsed();
                long total = mbean.getTotalCapacity();
                memoryUsageInfoList.add(new MemoryUsageInfo("BufferPool", mbean.getName(), used, total, Long.MIN_VALUE));
            }
        }catch (ClassNotFoundException e) {
            // ignore
        }
        return  memoryUsageInfoList;
    }


    /**
     *  Gcinfo Gc信息
     * @return
     */
    public List<GarbageInfo> gcInfoList(){
        List<GarbageInfo> garbageInfoList = new ArrayList<>();
        List<GarbageCollectorMXBean> garbageCollectorMxBeans = ManagementFactory.getGarbageCollectorMXBeans();
        GarbageInfo garbageInfo = null;
        for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorMxBeans) {
            String name = garbageCollectorMXBean.getName();
            String gcname = "gc." + name + ".count";
            String timename = "gc." + name + ".time(ms)";

            garbageInfo = GarbageInfo.builder()
                    // 数量
                    .name(gcname)
                    .count(garbageCollectorMXBean.getCollectionCount())
                    // 时长
                    .timeName(timename)
                    .time(garbageCollectorMXBean.getCollectionTime()).build();
            garbageInfoList.add(garbageInfo);
        }
        return garbageInfoList;
    }


}
